
package com.aris.voicechecking;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import org.apache.http.Header;
import org.json.JSONArray;
import org.json.JSONObject;

import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.os.Environment;
import android.os.StatFs;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.util.Patterns;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.FileAsyncHttpResponseHandler;
import com.voicecheck.provider.DataProviderV2;
import com.voicecheck.util.ConnectionProvider;
import com.voicecheck.v2.model.LessonModel;
import com.voicecheck.v2.model.SentencesModel;
import com.voicecheck.v2.model.UrlModel;

public class ConnectionActivity extends ActionBarActivity {

    protected EditText connect_url;

    protected DataProviderV2 dataprovider;

    protected SharedPreferences sharedpreferences;

    protected String url_string;

    protected LinearLayout download_component;

    protected ProgressBar progress;

    protected Boolean isDownloading;

    protected ImageView done_download;

    protected LinearLayout connect_url_bounder;

    protected ImageView btn_download;

    protected RelativeLayout adView;

    protected TextView download_state_txt;

    // protected Toast toastmsg;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_connection);

        initial();

        execution();
    }

    private void initial() {

        connect_url = (EditText)findViewById(R.id.connect_url);
        dataprovider = new DataProviderV2(this);
        download_component = (LinearLayout)findViewById(R.id.download_component);
        progress = (ProgressBar)findViewById(R.id.progress);
        isDownloading = false;
        done_download = (ImageView)findViewById(R.id.done_download);
        connect_url_bounder = (LinearLayout)findViewById(R.id.connect_url_bounder);
        btn_download = (ImageView)findViewById(R.id.btn_download);

        adView = (RelativeLayout)findViewById(R.id.adView);
        download_state_txt = (TextView)findViewById(R.id.download_state_txt);
    }

    private void execution() {

        adView.setBackgroundResource(R.drawable.banner);

        adView.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {

                Intent webviewIntent = new Intent(ConnectionActivity.this, WebviewActivity.class);
                startActivity(webviewIntent);
                overridePendingTransition(R.drawable.anim_slide_in_left,
                        R.drawable.anim_slide_out_left);

            }
        });

        download_state_txt.setText(getString(R.string.downloadstringtitle));

        btn_download.setOnClickListener(dllistener);
        done_download.setVisibility(View.GONE);
        done_download.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {

                // connect_url_bounder.setVisibility(View.VISIBLE);
                // download_component.setVisibility(View.GONE);
                Intent gohome = new Intent(ConnectionActivity.this, MainActivity.class);
                startActivity(gohome);
                overridePendingTransition(R.drawable.anim_slide_in_right,
                        R.drawable.anim_slide_out_right);
                finish();
            }
        });

        DataProviderV2 provider = new DataProviderV2(ConnectionActivity.this);
        // config url
        sharedpreferences = getSharedPreferences(getString(R.string.user_data),
                Context.MODE_PRIVATE);

        long index = sharedpreferences.getLong(getString(R.string.user_data_connect_link), 0);

        url_string = provider.retrieveURLByID(index).getUrl();

        if (url_string.equals("about:blank") || dataprovider.getWeekNumber() <= 1)
            url_string = "";

        connect_url.setText(url_string);

        connect_url.setHint(getString(R.string.hint_text));
        connect_url_bounder.setVisibility(View.VISIBLE);
        download_component.setVisibility(View.GONE);

        // configuration actionbar
        // getSupportActionBar().setTitle(getString(R.string.back));
        ActionBar actionBar = getSupportActionBar();
        ColorDrawable colorDrawable = new ColorDrawable(getResources().getColor(R.color.main_color));
        actionBar.setBackgroundDrawable(colorDrawable);
        actionBar.setDisplayShowCustomEnabled(true);
        actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM | ActionBar.DISPLAY_HOME_AS_UP);
        View actionbarcustomeview = getLayoutInflater().inflate(R.layout.actionbar_center_title,
                (ViewGroup)(getSupportActionBar().getCustomView()));

        TextView center_title = (TextView)actionbarcustomeview.findViewById(R.id.center_title);
        center_title.setText(getString(R.string.title_activity_connection));
        center_title.setTextColor(Color.WHITE);

        actionBar.setCustomView(actionbarcustomeview, new ActionBar.LayoutParams(
                ActionBar.LayoutParams.WRAP_CONTENT, ActionBar.LayoutParams.MATCH_PARENT,
                Gravity.CENTER));

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.lesson_detail, menu);

        return true;
    }

    Thread downthread;

    OnClickListener dllistener = new OnClickListener() {

        @Override
        public void onClick(View v) {

            if (isDownloading)
                return;

            DataProviderV2 provider = new DataProviderV2(ConnectionActivity.this);
            // config url
            sharedpreferences = getSharedPreferences(getString(R.string.user_data),
                    Context.MODE_PRIVATE);

            long index = sharedpreferences.getLong(getString(R.string.user_data_connect_link), 0);

            url_string = provider.retrieveURLByID(index).getUrl();

            isDownloading = true;

            InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(connect_url.getWindowToken(), 0);

            long bytesExternalAvailable = Environment.getExternalStorageDirectory()
                    .getUsableSpace();
            long megExternalAvailable = bytesExternalAvailable / 1048576;

            StatFs statFs = new StatFs(Environment.getRootDirectory().getAbsolutePath());
            @SuppressWarnings("deprecation")
            long freeval = (statFs.getAvailableBlocks() * statFs.getBlockSize());
            long megInternalAvailable = freeval / 1048576;

            System.out.println("Megs : " + megExternalAvailable + "  --- " + freeval);

            if (megExternalAvailable + megInternalAvailable < 40) {

                showMessage(getString(R.string.low_memory));

                isDownloading = false;
                return;
            }

            if (connect_url.getText().toString().trim().equals(url_string)) {

                int numOfWeed = dataprovider.getWeekNumber();

                if (numOfWeed == 8) {
                    showMessage(getString(R.string.package_has_been_downloaded));
                    isDownloading = false;
                    return;
                }

            }

            if (connect_url.getText().toString().equals("")
                    || !Patterns.WEB_URL.matcher(connect_url.getText().toString()).matches()) {

                showMessage(getString(R.string.bad_url));
                isDownloading = false;
                return;
            }

            if (!hasConnection()) {
                showMessage(getString(R.string.no_internet_access));
                isDownloading = false;
                return;
            }

            progress.setProgress(0);

            connect_url_bounder.setVisibility(View.GONE);
            download_component.setVisibility(View.VISIBLE);
            done_download.setVisibility(View.GONE);

            AsyncHttpClient client = new AsyncHttpClient();

            client.setTimeout(10000);
            client.setBasicAuth(ConnectionProvider.USER_NAME, ConnectionProvider.PASSWORD);

            client.get(connect_url.getText().toString().trim(), null,
                    new FileAsyncHttpResponseHandler(ConnectionActivity.this) {

                @Override
                public void onRetry(int retryNo) {

                };

                @Override
                public void onSuccess(int arg0, Header[] arg1, final File file) {

                    // download_state_txt.setText(getString(R.string.download_complete));
                    showMessageDoneDownload(getString(R.string.downloading_complete), file);

                }

                @Override
                public void onFailure(int arg0, Header[] arg1, Throwable arg2, File arg3) {

                    if (arg0 == 404) {
                        showMessage(getString(R.string.url_404));
                    } else {
                        showMessage(getString(R.string.fail_to_download_package));
                    }

                    connect_url_bounder.setVisibility(View.VISIBLE);
                    download_component.setVisibility(View.GONE);

                    isDownloading = false;
                }

                @Override
                public void onProgress(int bytesWritten, int totalSize) {
                    // Log.d("percent download --> ", bytesWritten +
                    // " / " + totalSize);

                    int percent = (int)(bytesWritten * 1.0 / totalSize * 100);

                    progress.setProgress(percent);

                };
            });

            // client.get("http://huy.pv:arisvnpvh1369@aris-vn.com/data-authen/package.zip",
            // new FileAsyncHttpResponseHandler(ConnectionActivity.this) {
            //
            // @Override
            // public void onRetry(int retryNo) {
            //
            // };
            //
            // @Override
            // public void onSuccess(int arg0, Header[] arg1, final File file) {
            //
            // //
            // download_state_txt.setText(getString(R.string.download_complete));
            // showMessageDoneDownload(getString(R.string.downloading_complete),
            // file);
            //
            // }
            //
            // @Override
            // public void onFailure(int arg0, Header[] arg1, Throwable arg2,
            // File arg3) {
            //
            // if (arg0 == 404) {
            // showMessage(getString(R.string.url_404));
            // } else {
            // showMessage(getString(R.string.fail_to_download_package));
            // }
            //
            // connect_url_bounder.setVisibility(View.VISIBLE);
            // download_component.setVisibility(View.GONE);
            //
            // isDownloading = false;
            // }
            //
            // @Override
            // public void onProgress(int bytesWritten, int totalSize) {
            // // Log.d("percent download --> ", bytesWritten +
            // // " / " + totalSize);
            //
            // int percent = (int)(bytesWritten * 1.0 / totalSize * 100);
            //
            // progress.setProgress(percent);
            //
            // };
            // }
            //
            // );
        }
    };

    private void copyFile(InputStream in, OutputStream out) throws IOException {

        byte[] buffer = new byte[1024];
        int read;

        while ((read = in.read(buffer)) != -1) {
            out.write(buffer, 0, read);
        }

    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == android.R.id.home) {
            onBackPressed();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onBackPressed() {

        if (isDownloading)
            return;

        super.onBackPressed();
        overridePendingTransition(R.drawable.anim_slide_in_right, R.drawable.anim_slide_out_right);
    }

    @Override
    protected void onPause() {
        super.onPause();

    }

    protected boolean unpackZip(String path, String zippath) {
        InputStream is;
        ZipInputStream zis;
        try {
            String filename;
            is = new FileInputStream(zippath);
            zis = new ZipInputStream(new BufferedInputStream(is));
            ZipEntry ze;
            byte[] buffer = new byte[1024];
            int count;

            String nameDirectory = "";

            while ((ze = zis.getNextEntry()) != null) {
                // zapis do souboru
                filename = ze.getName();

                if (!filename.contains("mp3") && !filename.contains("png")) {
                    nameDirectory += filename;
                }

                // Need to create directories if not exists, or
                // it will generate an Exception...
                if (ze.isDirectory()) {
                    File fmd = new File(path + "/" + filename);

                    fmd.mkdirs();
                    continue;
                }

                FileOutputStream fout = new FileOutputStream(path + "/" + filename);

                // cteni zipu a zapis
                while ((count = zis.read(buffer)) != -1) {
                    fout.write(buffer, 0, count);
                }

                fout.close();
                zis.closeEntry();
            }
            zis.close();

            if (!checkValidZipFile(nameDirectory)) {
                runOnUiThread(new Runnable() {

                    @Override
                    public void run() {
                        connect_url_bounder.setVisibility(View.VISIBLE);
                        download_component.setVisibility(View.GONE);
                    }
                });

                return false;
            }

        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }

        return true;
    }

    public Boolean checkValidZipFile(String zipcode) {

        if (zipcode.contains("lesson.json") && zipcode.contains("sentence.json")
                && zipcode.contains("audio") && zipcode.contains("image"))
            return true;

        return false;

    }

    private void fatecontent2Database(UrlModel urlModel, final ProgressDialog dialog) {

        try {
            FileInputStream stream = new FileInputStream(urlModel.getDir() + "/lesson.json");
            FileChannel fc = stream.getChannel();
            MappedByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());

            String jsonStr = Charset.defaultCharset().decode(bb).toString();
            stream.close();

            JSONArray jsonArr = new JSONArray(jsonStr);

            for (int i = 0; i < jsonArr.length(); i++) {
                JSONObject jobj = jsonArr.getJSONObject(i);

                LessonModel model = new LessonModel();
                model.setWeek(jobj.getInt("week"));
                model.setDay(jobj.getInt("day"));
                model.setLesson(jobj.getInt("lesson"));
                model.setSubject(jobj.getString("subject"));
                model.setDay_subject(jobj.getString("day_subject"));
                model.setCover_image(jobj.getString("cover_image"));
                model.setDone(jobj.getInt("done"));

                if( model.getWeek()== 1)
                    continue;

                dataprovider.insertLesson(model);
                Log.d("json", jobj.toString());
            }

        } catch (Exception e) {
        }

        try {
            FileInputStream stream = new FileInputStream(urlModel.getDir() + "/sentence.json");
            FileChannel fc = stream.getChannel();
            MappedByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());

            String jsonStr = Charset.defaultCharset().decode(bb).toString();
            stream.close();

            JSONArray jsonArr = new JSONArray(jsonStr);

            for (int i = 0; i < jsonArr.length(); i++) {
                JSONObject jobj = jsonArr.getJSONObject(i);

                SentencesModel model = new SentencesModel();

                model.setWeek(jobj.getInt("week"));
                model.setDay(jobj.getInt("day"));
                model.setLesson(jobj.getInt("lesson"));
                model.setCharacter(jobj.getString("character"));
                model.setQuestion_content(jobj.getString("question_content"));
                model.setRecognize(jobj.getString("recognize"));
                model.setAudio_name(jobj.getString("audio_name"));
                model.setSentences(jobj.getInt("sentence"));

                if( model.getWeek()== 1)
                    continue;
                dataprovider.insertSentences(model);
                Log.d("json", jobj.toString());
            }

            runOnUiThread(new Runnable() {

                @Override
                public void run() {
                    dialog.dismiss();

                    done_download.setVisibility(View.VISIBLE);
                    download_state_txt.setText(getString(R.string.download_complete));

                }
            });

        } catch (Exception e) {

        }

    }

    public void showMessage(String str) {

        AlertDialog.Builder builder1 = new AlertDialog.Builder(this);
        builder1.setMessage(str);
        builder1.setCancelable(false);
        builder1.setPositiveButton("OK", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int id) {

                dialog.cancel();
            }
        });

        AlertDialog alert11 = builder1.create();

        alert11.show();
    }

    public void showMessageDoneDownload(String str, final File file) {

        // available..load data from package

        final ProgressDialog dialog = ProgressDialog.show(ConnectionActivity.this, "",
                getString(R.string.loading));

        downthread = new Thread(new Runnable() {

            @Override
            public void run() {

                UrlModel urlModel = dataprovider.retrieveURLByURL(connect_url.getText().toString());
                Editor editoroutside = sharedpreferences.edit();

                if (urlModel == null) {

                    long urlId = dataprovider.insertUrlTable(connect_url.getText().toString());
                    urlModel = dataprovider.retrieveURLByID(urlId);
                }

                try {

                    long size = file.length();

                    Log.d("size download --> ", size + "");

                    InputStream inputStream = new FileInputStream(file);
                    File fileoutput = new File(getCacheDir().getAbsolutePath(), "package.zip");

                    OutputStream out = new FileOutputStream(fileoutput);
                    copyFile(inputStream, out);

                    file.delete();

                    Boolean valid = unpackZip(urlModel.getDir(), fileoutput.getAbsolutePath());

                    if (!valid) {

                        runOnUiThread(new Runnable() {

                            @Override
                            public void run() {

                                showMessage(getString(R.string.fail_to_unzip_package));

                                getString(R.string.fail_to_download_package);

                                dialog.dismiss();

                                connect_url.setVisibility(View.VISIBLE);
                                download_component.setVisibility(View.GONE);

                            }
                        });

                        isDownloading = false;
                        return;
                    }

                    fileoutput.delete();

                    out.close();
                    inputStream.close();
                } catch (Exception e) {

                } finally {

                }

                editoroutside.putLong(getString(R.string.user_data_connect_link), urlModel.getId());

                editoroutside.commit();

                fatecontent2Database(urlModel, dialog);
                isDownloading = false;

            }
        });

        downthread.start();

    }

    public boolean hasConnection() {
        ConnectivityManager cm = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);

        NetworkInfo wifiNetwork = cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
        if (wifiNetwork != null && wifiNetwork.isConnected()) {
            return true;
        }

        NetworkInfo mobileNetwork = cm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
        if (mobileNetwork != null && mobileNetwork.isConnected()) {
            return true;
        }

        NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
        if (activeNetwork != null && activeNetwork.isConnected()) {
            return true;
        }

        return false;
    }
}
